/**
 * @author Francesco Rosso, matr 592057
 */

package pcd1112.model;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;

import pcd1112.model.eccezioni.ErrorException;

public class Config {

	public enum Mode {
		real, teacherDefault
	}

	private String url = "http://www.math.unipd.it/~conti/teaching/PCD1112/project_config.txt";
	private int E, E_receive, E_send, E_signature, g, n, NSIM;
	private String PROTO;
	private double r, p;

	private static Config istanza = null;
	Properties propFile = null;
	private Mode currentMode = Mode.teacherDefault;
	private int delay = 0;

	private Config() {
		// inizializza();
	}

	public synchronized void inizializza() throws ErrorException {

		InputStream inStream = null;
		try {
			inStream = new URL(url).openStream();
		} catch (MalformedURLException e) {
			throw new ErrorException("Configuration Error. \nMalformed URL.",
					e.getMessage());
		} catch (IOException e) {
			throw new ErrorException(
					"Configuration Error. \nDoes the specified file exists?",
					e.getMessage());
		}

		propFile = new Properties();
		try {
			propFile.load(inStream);
		} catch (IOException e) {
			throw new ErrorException("Configuration Error", e.getMessage());
		}

		// carico i parametri dal file scaricato
		try {
			setE(Integer.parseInt(get("E")));
			setE_receive(Integer.parseInt(get("E_receive")));
			setE_send(Integer.parseInt(get("E_send")));
			setE_signature(Integer.parseInt(get("E_signature")));
			setG(Integer.parseInt(get("g")));
			setN(Integer.parseInt(get("n")));
			setNSIM(Integer.parseInt(get("NSIM")));
			setPROTO(get("PROTO"));
			setR(Double.parseDouble(get("r")));
			setP(Double.parseDouble(get("p")));
		} catch (NumberFormatException e) {
			throw new ErrorException("Configuration Error", e.getMessage());
		} catch (NullPointerException e) {
			throw new ErrorException("Configuration error: value not found",
					e.getMessage());
		}

	}

	public synchronized static Config getConfig() {
		if (istanza == null)
			istanza = new Config();
		return istanza;
	}

	private String get(String key) throws ErrorException {
		String prop = propFile.getProperty(key);
		if (prop == null)
			throw new ErrorException("Configuration Error", "Value " + key
					+ " not found in configuration file");
		return prop;
	}

	/**
	 * @return the currentMode
	 */
	public Mode getCurrentMode() {
		return currentMode;
	}

	/**
	 * @param currentMode
	 *            the currentMode to set
	 */
	public void setCurrentMode(Mode currentMode) {
		this.currentMode = currentMode;
	}

	/**
	 * @return the g
	 */
	public int getG() {
		return g;
	}

	/**
	 * @param g
	 *            the g to set
	 */
	private void setG(int g) {
		this.g = g;
	}

	/**
	 * @return the NSIM
	 */
	public int getNSIM() {
		return NSIM;
	}

	/**
	 * @param nSIM
	 *            the NSIM to set
	 */
	private void setNSIM(int nSIM) {
		NSIM = nSIM;
	}

	/**
	 * @return the e_receive
	 */
	public int getE_receive() {
		return E_receive;
	}

	/**
	 * @param e_receive
	 *            the e_receive to set
	 */
	private void setE_receive(int e_receive) {
		E_receive = e_receive;
	}

	/**
	 * @return the e_signature
	 */
	public int getE_signature() {
		return E_signature;
	}

	/**
	 * @param e_signature
	 *            the e_signature to set
	 */
	private void setE_signature(int e_signature) {
		E_signature = e_signature;
	}

	/**
	 * @return the E_send
	 */
	public int getE_send() {
		return E_send;
	}

	/**
	 * @param e_send
	 *            the E_send to set
	 */
	private void setE_send(int e_send) {
		E_send = e_send;
	}

	/**
	 * @return the Energy amount
	 */
	public int getE() {
		return E;
	}

	/**
	 * @param e
	 *            the Energy to set
	 */
	private void setE(int e) {
		E = e;
	}

	/**
	 * @return the number of nodes
	 */
	public int getN() {
		return n;
	}

	/**
	 * @param n
	 *            the number of nodes to set
	 */
	private void setN(int n) {
		this.n = n;
	}

	/**
	 * @return the PROTO
	 */
	public String getPROTO() {
		return PROTO;
	}

	/**
	 * @param pROTO
	 *            the pROTO to set
	 */
	private void setPROTO(String pROTO) {
		PROTO = pROTO;
	}

	/**
	 * @return the pprobability
	 */
	public double getP() {
		return p;
	}

	/**
	 * @param p
	 *            the pprobability to set
	 */
	private void setP(double p) {
		this.p = p;
	}

	/**
	 * @return the radius
	 */
	public double getR() {
		return r;
	}

	/**
	 * @param r
	 *            the radius to set
	 */
	private void setR(double r) {
		this.r = r;
	}

	/**
	 * @return the configuration url
	 */
	public String getUrl() {
		return url;
	}

	/**
	 * @param url
	 *            the configuration url to set
	 */
	public void setUrl(String url) {
		this.url = url;
	}

	public void setDelay(int delay) {
		this.delay = delay;
	}

	public int getDelay() {
		return delay;
	}
}
